#include "exceptions.h"
#include "table.h"
#include "util.h"

#include <fstream>

namespace Database
{

using std::ifstream;


Table::Table(const string& name)
    : refs_(0)
{
    // Read table spec
    // TODO: read data dir from conf
    string specFileName = "data/database1/" + name + ".spec";

    ifstream specFile(specFileName, ifstream::in);

    if(!specFile.is_open())
        throw ETableNotFound();

    string line, columnName;
    while(specFile.good())
    {
        getline(specFile, line);

        Util::trim(line);
        if(!line.length())
            continue;

        const size_t delim = line.find(" ");
        if(delim == line.npos)
            throw EColumnSpec();

        columnName = line.substr(0, delim);
        line.erase(0, delim);
        Util::ltrim(line);

        if(fields_.find(columnName) != fields_.end())
            throw ETableDuplicateColumn();

        fields_.insert(make_pair(columnName, ColumnSpec::fromString(line)));
    }

    specFile.close();
}


Table::~Table()
{
    if(refs_)
        throw ETableNotClosed();
}


Table& Table::open()
{
    if(++refs_ == 1)
    {
        // TODO - open table
    }

    return *this;
}


void Table::close()
{
    if(--refs_ < 1)
    {
        if(refs_ < 0)
            throw ETableNotOpen();

        // TODO - close table
    }
}


void Table::lockRead()
{
    readLock_.lock();
}


void Table::lockWrite()
{
    writeLock_.lock();
}


void Table::unlockRead()
{
    readLock_.unlock();
}


void Table::unlockWrite()
{
    writeLock_.unlock();
}

}   // namespace Database
